import time
import hashlib
import requests
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
import xmltodict
from sqlalchemy import exc

app = Flask(__name__)
app.config['JSON_AS_ASCII'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///offers.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)


# =============== 数据模型 ===============
class Offer(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    company = db.Column(db.String(50), nullable=False)
    position = db.Column(db.String(50))
    salary = db.Column(db.String(20))
    user = db.Column(db.String(50))  # 保留用户字段用于审计


# 初始化数据库
with app.app_context():
    db.create_all()


# =============== API路由 ===============
@app.route('/offers/<int:id>', methods=['GET'])
def get_offer(id):
    offer = Offer.query.get_or_404(id)
    return jsonify({
        "id": offer.id,
        "company": offer.company,
        "position": offer.position,
        "salary": offer.salary
    })


@app.route('/offers', methods=['GET'])
def list_offers():
    page = request.args.get('page', 1, type=int)
    per_page = request.args.get('per_page', 10, type=int)
    search_key = request.args.get('q', '')

    query = Offer.query
    if search_key:
        query = query.filter(Offer.company.ilike(f"%{search_key}%"))

    pagination = query.paginate(page=page, per_page=per_page, error_out=False)

    return jsonify({
        "total": pagination.total,
        "page": pagination.page,
        "per_page": pagination.per_page,
        "data": [{
            "id": item.id,
            "company": item.company,
            "position": item.position
        } for item in pagination.items]
    })


@app.route('/offers', methods=['POST'])
def create_offer():
    try:
        data = request.get_json()
        if isinstance(data, list):
            db.session.bulk_insert_mappings(Offer, data)
        else:
            db.session.add(Offer(**data))
        db.session.commit()
        return jsonify({"status": "success"})
    except exc.SQLAlchemyError as e:
        db.session.rollback()
        return jsonify({"error": str(e)}), 500


@app.route('/offers/<int:id>', methods=['PATCH'])
def update_offer(id):
    offer = Offer.query.get_or_404(id)
    data = request.get_json()
    for key in ['company', 'position', 'salary']:
        if key in data:
            setattr(offer, key, data[key])
    db.session.commit()
    return jsonify({"status": "updated"})


@app.route('/offers/<int:id>', methods=['DELETE'])
def delete_offer(id):
    offer = Offer.query.get_or_404(id)
    db.session.delete(offer)
    db.session.commit()
    return jsonify({"status": "deleted"})


@app.route('/offers/<int:id>', methods=['PUT'])
def replace_offer(id):
    data = request.get_json()
    offer = Offer.query.get_or_404(id)
    offer.company = data['company']
    offer.position = data['position']
    offer.salary = data['salary']
    db.session.commit()
    return jsonify({"status": "replaced"})


# =============== 微信公众号处理 ===============
WECHAT_TOKEN = "YOUR_TOKEN"


def format_wechat_reply(msg, content):
    return f'''<xml>
        <ToUserName><![CDATA[{msg['FromUserName']}]]></ToUserName>
        <FromUserName><![CDATA[{msg['ToUserName']}]]></FromUserName>
        <CreateTime>{int(time.time())}</CreateTime>
        <MsgType><![CDATA[text]]></MsgType>
        <Content><![CDATA[{content}]]></Content>
    </xml>'''


@app.route('/', methods=['GET', 'POST'])
def wechat_handler():
    if request.method == 'GET':
        # 微信服务器验证
        signature = request.args.get('signature', '')
        timestamp = request.args.get('timestamp', '')
        nonce = request.args.get('nonce', '')
        echostr = request.args.get('echostr', '')

        tmp_list = sorted([WECHAT_TOKEN, timestamp, nonce])
        sha1 = hashlib.sha1(''.join(tmp_list).encode()).hexdigest()
        return echostr if sha1 == signature else 'Verification Failed'

    # 处理用户消息
    xml_data = xmltodict.parse(request.data)
    msg = xml_data['xml']
    reply = "可用指令：\n搜索 关键词 [页码]\n创建 公司 职位 薪资\n更新 ID 公司 职位 薪资\n删除 ID\n批量创建 公司1,职位1,薪资1;公司2,职位2,薪资2"

    if msg['MsgType'] == 'text':
        try:
            content = msg['Content'].strip().split()
            if not content:
                return format_wechat_reply(msg, reply)

            command = content[0]
            params = content[1:]

            # 搜索功能
            if command == "搜索":
                keyword = params[0] if params else ""
                page = int(params[1]) if len(params) > 1 else 1
                resp = requests.get(f'http://localhost:5000/offers?q={keyword}&page={page}')
                if resp.status_code == 200:
                    items = resp.json()['data'][:5]
                    reply = '\n'.join([f"{i['company']} {i['position']}" for i in items]) or "无结果"

            # 创建单个
            elif command == "创建":
                if len(params) < 3:
                    raise ValueError("参数不足")
                data = {"company": params[0], "position": params[1], "salary": params[2]}
                requests.post('http://localhost:5000/offers', json=data)
                reply = "创建成功"

            # 批量创建
            elif command == "批量创建":
                raw_data = ' '.join(params).split(';')
                entries = []
                for entry in raw_data:
                    fields = entry.strip().split(',')
                    if len(fields) != 3:
                        raise ValueError(f"格式错误：{entry}")
                    entries.append({"company": fields[0], "position": fields[1], "salary": fields[2]})
                resp = requests.post('http://localhost:5000/offers', json=entries)
                reply = f"成功添加{len(entries)}条数据" if resp.ok else "批量创建失败"

            # 更新数据
            elif command == "更新":
                if len(params) < 4:
                    raise ValueError("参数不足")
                offer_id = params[0]
                data = {"company": params[1], "position": params[2], "salary": params[3]}
                requests.patch(f'http://localhost:5000/offers/{offer_id}', json=data)
                reply = "更新成功"

            # 删除数据
            elif command == "删除":
                if not params:
                    raise ValueError("缺少ID")
                requests.delete(f'http://localhost:5000/offers/{params[0]}')
                reply = "删除成功"

        except Exception as e:
            reply = f"错误：{str(e)}\n示例：\n创建 字节跳动 后端开发 30k\n批量创建 公司A,职位A,薪资A;公司B,职位B,薪资B"

    return format_wechat_reply(msg, reply)


if __name__ == '__main__':
    app.run(host="0.0.0.0", port=5000, debug=True)